// Create Images page (Create Dreams) - mobile-first, adapts to PC, supports dark/light mode
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import SelectPersion from './components/select_persion'; // 角色选择弹窗
import SelectPose from './components/select_Pose'; // Pose 选择弹窗
import SelectOutfit from './components/select_Outfit'; // Outfit 选择弹窗
import SelectBackground from './components/select_Background'; // Background 选择弹窗
import SelectExpression from './components/select_Expression'; // Expression 选择弹窗
import { request } from '@/utils/request';
import { generationManager } from '@/utils/generation';
import { useI18n, toApiLanguageCode } from '@/utils/in18';
import { message } from 'antd';
import { getStoredBearerToken } from '@/utils/auth';
import WorkList, { WorkListHandle } from './components/work_list';
import { ImagePreviewModal, WorkEditPop } from './components/edit_pop';
import { openLoginModal, setLoginReturnState } from '@/componets/loginModel';

const CreateImagePage: React.FC = () => {
    const [tab, setTab] = React.useState<'image' | 'video'>('image'); // selected top tab (Image/Video)
    const [showPicker, setShowPicker] = useState(false); // show character picker modal
    const [showPosePicker, setShowPosePicker] = useState(false); // pose picker modal
    const [selectedPoseUrl, setSelectedPoseUrl] = useState<string | null>(null);
    const [showOutfitPicker, setShowOutfitPicker] = useState(false); // outfit picker modal
    const [selectedOutfitUrl, setSelectedOutfitUrl] = useState<string | null>(null);
    const [showBackgroundPicker, setShowBackgroundPicker] = useState(false); // background picker modal
    const [selectedBackgroundUrl, setSelectedBackgroundUrl] = useState<string | null>(null);
    const [showExpressionPicker, setShowExpressionPicker] = useState(false); // expression picker modal
    const [showVideoComingSoon, setShowVideoComingSoon] = useState(false); // video coming soon placeholder
    const [selectedExpressionUrl, setSelectedExpressionUrl] = useState<string | null>(null);
    // use react-router location to read route state (e.g. image_url)
    const location = useLocation();
    const navigate = useNavigate();
    const navState = (location && (location as any).state) || {};
    const imageUrl = navState?.image_url ?? null;
    const [selectedImageUrl, setSelectedImageUrl] = useState<string | null>(imageUrl);
    // store selected items (used to show name / role_prompt / key_words etc.)
    const [selectedCharacter, setSelectedCharacter] = useState<any>(null);
    const [selectedPoseItem, setSelectedPoseItem] = useState<any>(null);
    const [selectedOutfitItem, setSelectedOutfitItem] = useState<any>(null);
    const [selectedBackgroundItem, setSelectedBackgroundItem] = useState<any>(null);
    const [selectedExpressionItem, setSelectedExpressionItem] = useState<any>(null);
    const cardClass = 'rounded-xl border border-dashed dark:border-[#89898A] border-[#2b2b2b] dark:bg-[#0f0f10] bg-[#FFFFFF] text-white'; // common card style
    const { locale, t } = useI18n();
    const [messageApi, contextHolder] = message.useMessage();
    const [previewUrl, setPreviewUrl] = useState<string | null>(null);// 预览图片（生成结果）
    const [previewWork, setPreviewWork] = useState<any | null>(null); // 预览作品（公开/删除）
    const [selfPrompt, setSelfPrompt] = useState<string>(''); // 自定义提示词相关状态
    const [isEditingPrompt, setIsEditingPrompt] = useState<boolean>(false);
    const workListRef = useRef<WorkListHandle | null>(null);// 子组件 WorkList 的 ref，用于在编辑弹层内操作后同步列表数据
    const [isRandomizing, setIsRandomizing] = useState<boolean>(false); // 随机选择按钮加载态
    const [belongsCategory, setBelongsCategory] = useState<string>('');// 角色类别（角色 category），用于请求时的 Belongs

    // 将 UI locale 映射为 /api/accessory 接口需要的 language 参数
    const resolveAccessoryLanguage = (loc?: any) => {
        try {
            const base = String(loc || '').split('-')[0].toLowerCase();
            if (base === 'es') return 'xby'; // 西班牙语
            if (base === 'fr') return 'fy';  // 法语
            if (base === 'ja') return 'jp';  // 日语
            if (base === 'en') return 'en';  // 英语
            if (base === 'ru') return 'ey';  // 俄语
        } catch { }
        return undefined;
    };

    useEffect(() => {
        console.log('接收到的值', navState)
        const hasImageUrl = !!navState?.image_url;
        setSelectedImageUrl(hasImageUrl ? String(navState.image_url) : null);
        // 仅当存在 image_url 时，才根据导航参数重建 selectedCharacter，避免清除后被误重建
        try {
            const tplId = (navState && (navState.template_id ?? navState.id)) as any;
            if (hasImageUrl && (typeof tplId === 'number' || (typeof tplId === 'string' && tplId))) {
                const normalizedId = Number(tplId);
                if (Number.isFinite(normalizedId)) {
                    const candidate: any = {
                        id: normalizedId,
                        image_url: String(navState.image_url),
                        name: navState?.name ?? selectedCharacter?.name ?? '',
                        role_prompt: navState?.role_prompt ?? selectedCharacter?.role_prompt ?? '',
                        // 从路由 state 恢复 category（如果有的话）
                        category: navState?.category ?? selectedCharacter?.category ?? undefined,
                    };
                    setSelectedCharacter(candidate);
                    // 同步 belongsCategory，确保随机选择可以读取到来自路由的 category
                    try {
                        if (candidate?.category) setBelongsCategory(String(candidate.category));
                    } catch { }
                }
            } else {
                // 当没有 image_url 时，不自动重建角色，确保清除后按钮状态恢复
                if (!hasImageUrl) {
                    setSelectedCharacter(null);
                }
            }
        } catch { }
    }, [location && (location as any).state]);

    // 登录回跳后尝试还原之前保存的选择
    useEffect(() => {
        try {
            const raw = sessionStorage.getItem('login:return_state');
            if (!raw) return;
            const state = JSON.parse(raw);
            if (state?.type !== 'createImage') return;
            // 只在首次进入时恢复一次，然后清除
            sessionStorage.removeItem('login:return_state');
            if (state.selectedImageUrl) setSelectedImageUrl(state.selectedImageUrl);
            if (state.selectedCharacter) setSelectedCharacter(state.selectedCharacter);
            if (state.selectedCharacter) setSelectedCharacter(state.selectedCharacter);
            // 登录回跳也可能包含 category
            if (state.selectedCharacter?.category) {
                setSelectedCharacter((sc: any) => ({ ...(sc || {}), category: state.selectedCharacter.category }));
                // 同步 belongsCategory
                try {
                    setBelongsCategory(String(state.selectedCharacter.category));
                } catch { }
            }
            if (state.selectedPoseUrl) setSelectedPoseUrl(state.selectedPoseUrl);
            if (state.selectedPoseItem) setSelectedPoseItem(state.selectedPoseItem);
            if (state.selectedOutfitUrl) setSelectedOutfitUrl(state.selectedOutfitUrl);
            if (state.selectedOutfitItem) setSelectedOutfitItem(state.selectedOutfitItem);
            if (state.selectedBackgroundUrl) setSelectedBackgroundUrl(state.selectedBackgroundUrl);
            if (state.selectedBackgroundItem) setSelectedBackgroundItem(state.selectedBackgroundItem);
            if (state.selectedExpressionUrl) setSelectedExpressionUrl(state.selectedExpressionUrl);
            if (state.selectedExpressionItem) setSelectedExpressionItem(state.selectedExpressionItem);
        } catch { }
    }, []);

    // 进入页面后自动获取随机配饰并填充（仅在对应项未选择时才填充）
    // useEffect(() => {
    //     (async () => {
    //         try {
    //             const payload: any = { types: ['Expression', 'background', 'pose', 'outfit'] };
    //             // 优先判断是否存在 category：优先使用已经同步的 belongsCategory，
    //             // 回退到 selectedCharacter?.category，再回退到 navState?.category
    //             const resolvedCategory = ((): string | undefined => {
    //                 try {
    //                     if (belongsCategory && String(belongsCategory).trim()) return String(belongsCategory).trim();
    //                 } catch { }
    //                 try {
    //                     if (selectedCharacter?.category && String(selectedCharacter.category).trim()) return String(selectedCharacter.category).trim();
    //                 } catch { }
    //                 try {
    //                     if (navState?.category && String(navState.category).trim()) return String(navState.category).trim();
    //                 } catch { }
    //                 return undefined;
    //             })();
    //             if (resolvedCategory) payload.Belongs = resolvedCategory;
    //             // 传递 language 字段到后端
    //             try {
    //                 const accessoryLang = resolveAccessoryLanguage(locale);
    //                 if (accessoryLang) payload.language = accessoryLang;
    //             } catch { }

    //             const res = await request.post('/api/accessory/getRandomAccessories', payload);
    //             const list: any[] = Array.isArray(res?.data?.data) ? res.data.data : [];
    //             if (list.length === 0) return;
    //             const byType: Record<string, any> = {};
    //             for (const it of list) {
    //                 if (it && typeof it === 'object' && it.type) {
    //                     byType[String(it.type).toLowerCase()] = it;
    //                 }
    //             }
    //             // Expression
    //             if (!selectedExpressionItem && byType['expression']) {
    //                 const it = byType['expression'];
    //                 if (it?.image_url) setSelectedExpressionUrl(String(it.image_url));
    //                 setSelectedExpressionItem(it);
    //             }
    //             // background
    //             if (!selectedBackgroundItem && byType['background']) {
    //                 const it = byType['background'];
    //                 if (it?.image_url) setSelectedBackgroundUrl(String(it.image_url));
    //                 setSelectedBackgroundItem(it);
    //             }
    //             // pose
    //             if (!selectedPoseItem && byType['pose']) {
    //                 const it = byType['pose'];
    //                 if (it?.image_url) setSelectedPoseUrl(String(it.image_url));
    //                 setSelectedPoseItem(it);
    //             }
    //             // outfit
    //             if (!selectedOutfitItem && byType['outfit']) {
    //                 const it = byType['outfit'];
    //                 if (it?.image_url) setSelectedOutfitUrl(String(it.image_url));
    //                 setSelectedOutfitItem(it);
    //             }
    //         } catch { }
    //     })();
    //     // 仅首屏触发一次；具体填充逻辑内部会判断是否已选择
    //     // eslint-disable-next-line react-hooks/exhaustive-deps
    // }, []);
    // 清除选中的图片
    const handleClearImage = () => {
        // 清除本地状态
        setSelectedImageUrl(null);
        setSelectedCharacter(null);
        // 清除 belongsCategory，确保随机时不传 Belongs
        setBelongsCategory('');
        try {
            // 从 navState 复制并删除相关参数，然后替换当前 history state
            const newState = { ...(navState || {}) } as Record<string, any>;
            if ('image_url' in newState) delete newState.image_url;
            if ('template_id' in newState) delete newState.template_id;
            if ('id' in newState) delete newState.id;
            if ('role_prompt' in newState) delete newState.role_prompt;
            if ('name' in newState) delete newState.name;
            navigate(location.pathname + location.search, { replace: true, state: newState });
        } catch (e) {
            // ignore
        }
    };

    // 点击“随机选择”按钮：重新获取随机配饰并替换现有选择（不改变已选角色/role_prompt）
    const handleRandomizeAccessories = async () => {
        if (isRandomizing) return;
        setIsRandomizing(true);
        try {
            // 内部方法：请求并按类型归类
            const fetchOnce = async () => {
                // 未选角色：不传 Belongs；已选且有 category：传 Belongs=category
                const hasBelongs = !!(belongsCategory && String(belongsCategory).trim());
                const payload: any = {
                    types: ['Expression', 'background', 'pose', 'outfit'],
                };
                if (hasBelongs) {
                    payload.Belongs = String(belongsCategory).trim();
                }
                const res = await request.post('/api/accessory/getRandomAccessories', payload);
                const list: any[] = Array.isArray(res?.data?.data) ? res.data.data : [];
                const byType: Record<string, any> = {};
                for (const it of list) {
                    if (it && typeof it === 'object' && it.type) {
                        byType[String(it.type).toLowerCase()] = it;
                    }
                }
                return byType;
            };

            let byType = await fetchOnce();
            const required = ['expression', 'background', 'pose', 'outfit'];
            let hasAll = required.every((k) => byType[k]?.image_url);
            // 若不完整，重试一次
            if (!hasAll) {
                byType = await fetchOnce();
                hasAll = required.every((k) => byType[k]?.image_url);
            }

            if (!hasAll) {
                messageApi.error(t('messageApi.randomize_incomplete'));
                return;
            }

            const expr = byType['expression'];
            const bg = byType['background'];
            const pose = byType['pose'];
            const outfit = byType['outfit'];

            // 原子更新：一次性替换四类配饰
            setSelectedExpressionUrl(String(expr.image_url));
            setSelectedExpressionItem(expr);
            setSelectedBackgroundUrl(String(bg.image_url));
            setSelectedBackgroundItem(bg);
            setSelectedPoseUrl(String(pose.image_url));
            setSelectedPoseItem(pose);
            setSelectedOutfitUrl(String(outfit.image_url));
            setSelectedOutfitItem(outfit);

            messageApi.success(t('messageApi.randomize_success'));
        } catch (e) {
            console.error('随机获取配饰失败:', e);
            messageApi.error(t('messageApi.randomize_failed'));
        } finally {
            setIsRandomizing(false);
        }
    };

    return (
        <div className='w-full pb-24 text-white dark:text-white  dark:bg-[#0b0b0b] '>
            {contextHolder}
            {/* 页面容器，移动端宽度约 92%，PC 更宽的固定容器 */}
            <div className='relative mx-auto md:w-[70%] lg:w-[54%] xl:w-[60%] 2xl:w-[56%] w-[92%] lg:max-w-5xl xl:max-w-6xl 2xl:max-w-[1280px]'>
                {/* 标题区（居中） */}
                <div className='pt-3 md:pt-8 text-center'>
                    <div className='flex items-end justify-center'>
                        <div className='text-[1.6rem] md:text-[2.4rem] font-extrabold'>
                            <span className='text-black dark:text-[#FAFAFA]'>{t('CreatImg.title_create')}</span>
                            <span className='ml-1' style={{ color: '#ff87bb' }}>{t('CreatImg.title_dreams')}</span>
                        </div>
                    </div>
                    <div className='mt-1 text-[0.8rem] text-[#9ea3a8]'>
                        <span>{t('CreatImg.see_featured')}</span>
                    </div>
                </div>

                {/* 顶部 Tabs 切换（Image/Video）——与选择区域同宽 */}
                <div className='mt-3'>
                    <div className='bg-[#666666] dark:bg-[#18181A] border border-[#fbfbfb] dark:border-[#2a2a2a] rounded-lg w-full'>
                        <div className='grid grid-cols-2 gap-1'>
                            {/* 图片按钮 */}
                            <button
                                onClick={() => setTab('image')}
                                style={tab === 'image' ? { background: 'linear-gradient(to right, rgb(236, 72, 153), rgb(244, 114, 182), rgb(236, 72, 153))' } : undefined}
                                className={`h-10 rounded-md text-sm flex items-center justify-center w-full ${tab === 'image' ? 'text-white' : 'text-[#cbd0d5]'} transition-colors`}
                            >
                                <span className='mr-2' >
                                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-image size-4"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"></rect><circle cx="9" cy="9" r="2"></circle><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"></path></svg>
                                </span>
                                <span className='flex items-center'>{t('CreatImg.tab_image')}</span>
                            </button>
                            {/* 视频按钮 */}
                            <button
                                onClick={() => {
                                    setTab('video');
                                    setShowVideoComingSoon(true);
                                }}
                                style={tab === 'video' ? { background: 'linear-gradient(to right, rgb(236, 72, 153), rgb(244, 114, 182), rgb(236, 72, 153))' } : undefined}
                                className={`h-10 rounded-md text-sm flex items-center justify-center w-full  ${tab === 'video' ? 'text-white' : 'text-[#cbd0d5]'} transition-colors`}
                            >
                                <span className='mr-2' >
                                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-video size-4"><path d="m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5"></path><rect x="2" y="6" width="14" height="12" rx="2"></rect></svg>                                </span>
                                <span className='flex items-center'>{t('CreatImg.tab_video')}</span>
                            </button>
                        </div>
                    </div>
                </div>

                {/*左侧是角色区域，右侧是动作区域*/}
                <div className='mt-2 grid grid-cols-2 gap-2 md:gap-3 lg:gap-4'>
                    {/* 角色选择（左） */}
                    <div style={{ border: "0.1px solid #EC4899" }} className={` cursor-pointer col-span-1 rounded-xl overflow-hidden hover:bg-[#fb8cd480] dark:hover:bg-[#200F1A] transition-colors duration-200`}>
                        <div className='relative h-full md:h-[28rem] lg:h-[32rem] xl:h-[36rem] 2xl:h-[40rem] flex items-center justify-center overflow-hidden' onClick={() => setShowPicker(true)}>
                            {selectedImageUrl ? (
                                <>
                                    {/* 后期需要修改为视频，截取首帧做封面  */}
                                    <img src={String(selectedImageUrl)} alt={t('CreatImg.alt_character')} className='absolute inset-0 w-full h-full object-cover' />
                                    {/* 显示选中项名字 */}
                                    {selectedCharacter?.name && (
                                        <div className='absolute left-1  right-1  bg-gradient-to-t from-black/60 to-transparent bottom-0 text-center'>
                                            <span className='px-2 py-1 rounded text-white text-base font-semibold truncate inline-block max-w-full'>
                                                {selectedCharacter.name}
                                            </span>
                                        </div>
                                    )}
                                    <button
                                        onClick={(e) => { e.stopPropagation(); handleClearImage(); }}
                                        aria-label={t('CreatImg.aria_remove_selected_character')}
                                        className='absolute top-2 right-2 w-8 h-8 rounded-full bg-black/40 hover:bg-black/60 text-white flex items-center justify-center'
                                    >
                                        ×
                                    </button>
                                </>
                            ) : (
                                <div className='animate-bounce text-center flex flex-col items-center justify-center'>
                                    <div className='text-[#878788]'>
                                        <svg stroke="currentColor" fill="currentColor" strokeWidth="0" viewBox="0 0 512 512" className="size-6 opacity-50" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M256 256a112 112 0 1 0-112-112 112 112 0 0 0 112 112zm0 32c-69.42 0-208 42.88-208 128v64h416v-64c0-85.12-138.58-128-208-128z"></path></svg>
                                    </div>
                                    <div className='text-sm font-semibold text-[#2b2b2b] dark:text-[#cbd0d5]'>{t('CreatImg.character')}</div>
                                    <div className='text-[10px] mt-1 text-[#2b2b2b] dark:text-[#71717A]'>{t('CreatImg.required')}</div>
                                </div>
                            )}
                        </div>
                    </div>

                    {/* 动作区域（右） */}
                    <div onClick={() => {
                        if (!selectedCharacter) {
                            try { messageApi.warning(t('CreatImg.select_character_first')); } catch { }
                            return;
                        }
                        console.log('selectedCharacter', selectedCharacter);
                        setShowPosePicker(true);
                    }} className={`cursor-pointer col-span-1 ${cardClass}`}>
                        <div className='h-full min-h-80 md:min-h-[28rem] lg:min-h-[32rem] xl:min-h-[36rem] 2xl:min-h-[40rem] flex items-center justify-center overflow-auto rounded-xl cursor-pointer relative hover:bg-[#18181b51] dark:hover:bg-[#18181B] transition-colors duration-200' >
                            {selectedPoseUrl ? (
                                <>
                                    {/* 后期需要修改为视频，截取首帧做封面  */}
                                    <img src={selectedPoseUrl} alt={t('CreatImg.alt_pose')} className='absolute inset-0 w-full h-full object-cover' />
                                    {/* {selectedPoseItem?.name && (
                                        <div className='absolute left-1 bottom-1 right-1 text-center'>
                                            <span className='px-2 py-1 rounded bg-black/60 text-white text-xs font-semibold truncate inline-block max-w-full'>
                                                {selectedPoseItem.name}
                                            </span>
                                        </div>
                                    )} */}
                                    <button
                                        onClick={(e) => { e.stopPropagation(); setSelectedPoseUrl(null); setSelectedPoseItem(null); }}
                                        aria-label={t('CreatImg.aria_clear_selected_pose')}
                                        className='absolute top-2 right-2 w-8 h-8 rounded-full bg-black/40 hover:bg-black/60 text-white flex items-center justify-center'
                                    >
                                        ×
                                    </button>
                                </>
                            ) : (
                                <div className='text-center flex flex-col items-center justify-center'>
                                    <div className='text-[#878788]'>
                                        <svg stroke="currentColor" fill="currentColor" strokeWidth="0" viewBox="0 0 512 512" className="size-6 opacity-50" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="255.75" cy="56" r="56"></circle><path d="m394.63 277.9-10.33-34.41v-.11l-22.46-74.86h-.05l-2.51-8.45a44.87 44.87 0 0 0-43-32.08h-120a44.84 44.84 0 0 0-43 32.08l-2.51 8.45h-.06l-22.46 74.86v.11l-10.37 34.41c-3.12 10.39 2.3 21.66 12.57 25.14a20 20 0 0 0 25.6-13.18l25.58-85.25 2.17-7.23a8 8 0 0 1 15.53 2.62 7.78 7.78 0 0 1-.17 1.61L155.43 347.4a16 16 0 0 0 15.32 20.6h29v114.69c0 16.46 10.53 29.31 24 29.31s24-12.85 24-29.31V368h16v114.69c0 16.46 10.53 29.31 24 29.31s24-12.85 24-29.31V368h30a16 16 0 0 0 15.33-20.6l-43.74-145.81a7.52 7.52 0 0 1-.16-1.59 8 8 0 0 1 15.54-2.63l2.17 7.23 25.57 85.25A20 20 0 0 0 382.05 303c10.27-3.44 15.69-14.71 12.58-25.1z"></path></svg>
                                    </div>
                                    <div className='text-xs text-[#2b2b2b] dark:text-[#cbd0d5]'>{t('CreatImg.pose')}</div>
                                    <div className='text-[10px] mt-1 text-[#2b2b2b] dark:text-[#71717A]'>{t('CreatImg.optional')}</div>
                                </div>
                            )}
                        </div>
                    </div>
                </div>

                {/* 最下方：背景区、服饰区、表情区 并排等分宽度 */}
                <div className='mt-2 grid grid-cols-3 gap-2 md:gap-3 lg:gap-4 '>
                    {/* 选则背景区域  */}
                    <div onClick={() => { console.log('selectedCharacter', selectedCharacter); setShowBackgroundPicker(true); }} className={`cursor-pointer ${cardClass}`}>
                        <div className='h-28 md:h-36 lg:h-40 xl:h-44 2xl:h-48 flex items-center overflow-auto rounded-xl justify-center relative hover:bg-[#18181b51] dark:hover:bg-[#18181B] transition-colors duration-200'>
                            {selectedBackgroundUrl ? (
                                <>
                                    <img src={selectedBackgroundUrl} alt={t('CreatImg.alt_background')} className='absolute inset-0 w-full h-full object-cover' />
                                    {/* {selectedBackgroundItem?.name && (
                                        <div className='absolute left-1 bottom-1 right-1 text-center'>
                                            <span className='px-2 py-1 rounded bg-black/60 text-white text-xs font-semibold truncate inline-block max-w-full'>
                                                {selectedBackgroundItem.name}
                                            </span>
                                        </div>
                                    )} */}
                                    <button
                                        onClick={(e) => { e.stopPropagation(); setSelectedBackgroundUrl(null); setSelectedBackgroundItem(null); }}
                                        aria-label={t('CreatImg.aria_clear_selected_background')}
                                        className='absolute top-2 right-2 w-8 h-8 rounded-full bg-black/40 hover:bg-black/60 text-white flex items-center justify-center'
                                    >
                                        ×
                                    </button>
                                </>
                            ) : (
                                <div className='text-center flex flex-col items-center justify-center'>
                                    <div className='text-[#878788]'><svg stroke="currentColor" fill="currentColor" strokeWidth="0" viewBox="0 0 256 256" className="size-6 opacity-50" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M164,80a28,28,0,1,0-28-28A28,28,0,0,0,164,80Zm0-40a12,12,0,1,1-12,12A12,12,0,0,1,164,40Zm90.88,155.92-54.56-92.08A15.87,15.87,0,0,0,186.55,96h0a15.85,15.85,0,0,0-13.76,7.84L146.63,148l-44.84-76.1a16,16,0,0,0-27.58,0L1.11,195.94A8,8,0,0,0,8,208H248a8,8,0,0,0,6.88-12.08ZM88,80l23.57,40H64.43ZM22,192l33-56h66l18.74,31.8,0,0L154,192Zm150.57,0-16.66-28.28L186.55,112,234,192Z"></path></svg></div>
                                    <div className='text-xs text-[#2b2b2b] dark:text-[#cbd0d5]'>{t('CreatImg.background')}</div>
                                    <div className='text-[10px] mt-1 text-[#2b2b2b] dark:text-[#71717A]'>{t('CreatImg.optional')}</div>
                                </div>
                            )}
                        </div>
                    </div>

                    {/* 选则服饰区域  */}
                    <div onClick={() => {
                        if (!selectedCharacter) {
                            try { messageApi.error(t('CreatImg.select_character_first')); } catch { }
                            return;
                        }
                        console.log('selectedCharacter', selectedCharacter);
                        setShowOutfitPicker(true);
                    }} className={`cursor-pointer ${cardClass}`}>
                        <div className='h-28 md:h-36 lg:h-40 xl:h-44 2xl:h-48 flex items-center overflow-auto relative rounded-xl justify-center hover:bg-[#18181b51] dark:hover:bg-[#18181B] transition-colors duration-200'>
                            {selectedOutfitUrl ? (
                                <>
                                    <img src={selectedOutfitUrl} alt={t('CreatImg.alt_outfit')} className='absolute inset-0 w-full h-full object-cover' />
                                    {/* {selectedOutfitItem?.name && (
                                        <div className='absolute left-1 bottom-1 right-1 text-center'>
                                            <span className='px-2 py-1 rounded bg-black/60 text-white text-xs font-semibold truncate inline-block max-w-full'>
                                                {selectedOutfitItem.name}
                                            </span>
                                        </div>
                                    )} */}
                                    <button
                                        onClick={(e) => { e.stopPropagation(); setSelectedOutfitUrl(null); setSelectedOutfitItem(null); }}
                                        aria-label={t('CreatImg.aria_clear_selected_outfit')}
                                        className='absolute top-2 right-2 w-8 h-8 rounded-full bg-black/40 hover:bg-black/60 text-white flex items-center justify-center'
                                    >
                                        ×
                                    </button>
                                </>
                            ) : (
                                <div className='text-center flex flex-col items-center justify-center'>
                                    <div className='text-[#878788]'><svg stroke="currentColor" fill="currentColor" strokeWidth="0" viewBox="0 0 256 256" className="size-6 opacity-50" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M217,34.8a15.94,15.94,0,0,0-14.82-1.71C188.15,38.55,159.82,47.71,128,47.71S67.84,38.55,53.79,33.09A16,16,0,0,0,32,48v55.77c0,35.84,9.65,69.65,27.18,95.18,18.16,26.46,42.6,41,68.82,41s50.66-14.57,68.82-41C214.35,173.44,224,139.63,224,103.79V48A16,16,0,0,0,217,34.8ZM78,133.33A8,8,0,1,1,66,122.66C71.75,116.28,82.18,112,92,112s20.25,4.28,26,10.66A8,8,0,1,1,106,133.33c-2.68-3-8.85-5.33-14-5.33S80.64,130.34,78,133.33Zm90.49,47.86a52.9,52.9,0,0,1-80.9,0A8,8,0,1,1,99.72,170.8a36.89,36.89,0,0,0,56.56,0,8,8,0,0,1,12.17,10.39ZM189.34,134a8,8,0,0,1-11.3-.63c-2.68-3-8.85-5.33-14-5.33s-11.36,2.34-14,5.33A8,8,0,1,1,138,122.66c5.71-6.38,16.14-10.66,26-10.66s20.25,4.28,26,10.66A8,8,0,0,1,189.34,134Z"></path></svg></div>
                                    <div className='text-xs text-[#2b2b2b] dark:text-[#cbd0d5]'>{t('CreatImg.outfit')}</div>
                                    <div className='text-[10px] mt-1 text-[#2b2b2b] dark:text-[#71717A]'>{t('CreatImg.optional')}</div>
                                </div>
                            )}
                        </div>
                    </div>

                    {/* 选则表情区域  */}
                    <div onClick={() => {
                        if (!selectedCharacter) {
                            try { messageApi.error(t('CreatImg.select_character_first')); } catch { }
                            return;
                        }
                        console.log('selectedCharacter', selectedCharacter);
                        setShowExpressionPicker(true);
                    }} className={`cursor-pointer ${cardClass}`}>
                        <div className='h-28 md:h-36 lg:h-40 xl:h-44 2xl:h-48 flex items-center overflow-auto relative rounded-xl justify-center hover:bg-[#18181b51] dark:hover:bg-[#18181B] transition-colors duration-200'>
                            {selectedExpressionUrl ? (
                                <>
                                    <img src={selectedExpressionUrl} alt={t('CreatImg.alt_expression')} className='absolute inset-0 w-full h-full object-cover' />
                                    {/* {selectedExpressionItem?.name && (
                                        <div className='absolute left-1 bottom-1 right-1 text-center'>
                                            <span className='px-2 py-1 rounded bg-black/60 text-white text-xs font-semibold truncate inline-block max-w-full'>
                                                {selectedExpressionItem.name}
                                            </span>
                                        </div>
                                    )} */}
                                    <button
                                        onClick={(e) => { e.stopPropagation(); setSelectedExpressionUrl(null); setSelectedExpressionItem(null); }}
                                        aria-label={t('CreatImg.aria_clear_selected_expression')}
                                        className='absolute top-2 right-2 w-8 h-8 rounded-full bg-black/40 hover:bg-black/60 text-white flex items-center justify-center'
                                    >
                                        ×
                                    </button>
                                </>
                            ) : (
                                <div className='text-center flex flex-col items-center justify-center'>
                                    <div className='dark:text-[#4E4E4F] text-[#c6c6c6]'>
                                        <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4779" width="20" height="20"><path d="M966.656 73.728q25.6 58.368 33.792 110.592 3.072 22.528 3.072 46.08t-5.632 45.056-18.944 40.448-35.84 31.232q-2.048 2.048-5.12 2.56t-5.12 2.56q14.336 36.864 21.504 76.8t7.168 81.92q0 93.184-35.328 174.592t-95.744 142.336-142.336 96.256-174.08 35.328q-93.184 0-174.592-35.328t-142.336-96.256-96.256-142.336-35.328-174.592q0-81.92 28.672-156.672l-7.168-4.096-7.168-3.072q-23.552-12.288-36.352-31.232t-18.944-40.448-5.632-45.056 3.584-46.08q8.192-52.224 33.792-110.592 11.264 34.816 25.6 68.608 12.288 28.672 29.696 58.368t37.888 49.152q61.44-86.016 156.16-136.192t208.384-50.176q55.296 0 107.52 13.312t98.304 37.376 85.504 57.856 70.144 75.776q20.48-20.48 36.864-49.664t28.672-56.832q14.336-32.768 25.6-67.584zM248.832 274.432q13.312 43.008 28.672 78.848 13.312 30.72 29.696 59.904t33.792 37.376q17.408 9.216 36.864 1.536t35.84-20.992q18.432-15.36 37.888-38.912zM766.976 638.976q1.024-2.048 1.024-7.168t-1.536-11.264-6.144-11.264-12.8-8.192q-23.552 28.672-58.368 51.2-29.696 19.456-75.264 35.328t-107.008 15.872q-60.416 0-103.936-15.872t-73.216-35.328q-33.792-22.528-57.344-51.2-8.192 2.048-12.288 7.168t-6.144 11.264-2.048 11.264 1.024 8.192q1.024 1.024 1.024 3.072 9.216 27.648 32.768 51.712t57.344 41.984 76.288 27.648 89.6 9.728q93.184 0 160.768-33.792t92.16-89.088q0-2.048 1.024-4.096t3.072-7.168zM681.984 450.56q17.408-8.192 33.792-37.376t29.696-59.904q15.36-35.84 28.672-78.848l-202.752 117.76q19.456 23.552 37.888 38.912 16.384 13.312 35.84 20.992t36.864-1.536z" fill="currentColor" /></svg></div>
                                    <div className='text-xs text-[#2b2b2b] dark:text-[#dbdcdd]'>{t('CreatImg.expression')}</div>
                                    <div className='text-[10px] mt-1 text-[#2b2b2b] dark:text-[#71717A]'>{t('CreatImg.optional')}</div>
                                </div>
                            )}
                        </div>
                    </div>
                </div>

                {/* 顶部操作：随机选择配饰 */}
                <div className='mt-2 flex'>
                    <button
                        onClick={handleRandomizeAccessories}
                        disabled={isRandomizing}
                        style={{ background: 'linear-gradient(to right, rgb(236, 72, 153), rgb(244, 114, 182), rgb(236, 72, 153))', opacity: isRandomizing ? 0.6 : 1 }}
                        className='h-14 w-full px-4 rounded-md text-sm font-medium text-white hover:opacity-90 transition-opacity flex items-center justify-center'
                    >
                        <span className='mr-2'>
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-dice-5"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><path d="M8 8h.01"></path><path d="M16 8h.01"></path><path d="M8 16h.01"></path><path d="M16 16h.01"></path><path d="M12 12h.01"></path></svg>
                        </span>
                        {isRandomizing ? t('CreatImg.randomizing') : t('CreatImg.randomize')}
                    </button>
                </div>

                {/* 自定义提示词区域 + Presets 模式选择 */}
                <div className={`mt-2 overflow-hidden ${cardClass}`}>
                    <div className=' md:p-5 lg:p-6 hover:bg-[#18181b51] dark:hover:bg-[#18181B] transition-colors duration-200'>
                        <div className='h-28 md:h-36 lg:h-40 rounded-lg p-3  md:p-4 lg:p-5 cursor-pointer' onClick={() => setIsEditingPrompt(true)}>
                            {!isEditingPrompt ? (
                                <div className='text-center h-full flex flex-col items-center justify-center'>
                                    {selfPrompt ? (
                                        <div className='w-full h-full flex items-center justify-center'>
                                            <p className='text-sm text-[#2b2b2b] dark:text-[#cbd0d5] text-center break-words overflow-hidden'>
                                                {selfPrompt}
                                            </p>
                                        </div>
                                    ) : (
                                        <>
                                            <div className='text-[#878788]'>
                                                <svg stroke="currentColor" fill="currentColor" strokeWidth="0" viewBox="0 0 256 256" className="size-6 opacity-50" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M232,32a8,8,0,0,0-8-8c-44.08,0-89.31,49.71-114.43,82.63A60,60,0,0,0,32,164c0,30.88-19.54,44.73-20.47,45.37A8,8,0,0,0,16,224H92a60,60,0,0,0,57.37-77.57C182.3,121.31,232,76.08,232,32ZM124.42,113.55q5.14-6.66,10.09-12.55A76.23,76.23,0,0,1,155,121.49q-5.9,4.94-12.55,10.09A60.54,60.54,0,0,0,124.42,113.55Zm42.7-2.68a92.57,92.57,0,0,0-22-22c31.78-34.53,55.75-45,69.9-47.91C212.17,55.12,201.65,79.09,167.12,110.87Z" /></svg>
                                            </div>
                                            <p className='text-sm text-[#2b2b2b] dark:text-[#cbd0d5]'>{t('CreatImg.custom_prompt')}</p>
                                            <p className='ml-2 text-xs text-[#EC4899]'>{t('CreatImg.premium_feature')}</p>
                                        </>
                                    )}
                                </div>
                            ) : (
                                <div className='h-full flex flex-col relative'>
                                    <textarea
                                        value={selfPrompt}
                                        onChange={(e) => setSelfPrompt(e.target.value)}
                                        onBlur={() => setIsEditingPrompt(false)}
                                        onKeyDown={(e) => {
                                            if (e.key === 'Enter' && !e.shiftKey) {
                                                e.preventDefault();
                                                setIsEditingPrompt(false);
                                            }
                                            if (e.key === 'Escape') {
                                                setIsEditingPrompt(false);
                                            }
                                        }}
                                        placeholder={t('CreatImg.custom_prompt')}
                                        className='w-full h-full resize-none border-none outline-none bg-transparent text-sm text-[#2b2b2b] dark:text-[#cbd0d5] placeholder-[#878788] focus:ring-2 focus:ring-[#EC4899] focus:ring-opacity-50 rounded-md p-2'
                                        autoFocus
                                    />
                                    <div className='absolute bottom-2 right-2 text-xs text-[#878788]'>
                                        {t('CreatImg.prompt_shortcuts')}
                                    </div>
                                </div>
                            )}
                        </div>
                    </div>
                </div>

                {/* 角色选择弹窗 */}
                {showPicker && (
                    <SelectPersion
                        onSelect={(item: any) => {
                            if (item?.image_url) setSelectedImageUrl(String(item.image_url));
                            setSelectedCharacter(item || null);
                            try {
                                if (item?.category) setBelongsCategory(String(item.category));
                                else setBelongsCategory('');
                            } catch { }
                            setShowPicker(false);
                        }}
                        onClose={() => setShowPicker(false)}
                    />
                )}

                {/* Pose 选择弹窗（select_Pose） */}
                {showPosePicker && (
                    <SelectPose
                        belongs={belongsCategory || selectedCharacter?.category}
                        onSelect={(item: any) => {
                            if (item?.image_url) setSelectedPoseUrl(String(item.image_url));
                            setSelectedPoseItem(item || null);
                            setShowPosePicker(false);
                        }}
                        onClose={() => setShowPosePicker(false)}
                    />
                )}

                {/* Outfit 选择弹窗（select_Outfit） */}
                {showOutfitPicker && (
                    <SelectOutfit
                        belongs={belongsCategory || selectedCharacter?.category}
                        onSelect={(item: any) => {
                            if (item?.image_url) setSelectedOutfitUrl(String(item.image_url));
                            setSelectedOutfitItem(item || null);
                            setShowOutfitPicker(false);
                        }}
                        onClose={() => setShowOutfitPicker(false)}
                    />
                )}

                {/* Background 选择弹窗（select_Background） */}
                {showBackgroundPicker && (
                    <SelectBackground
                        belongs={belongsCategory || selectedCharacter?.category}
                        onSelect={(item: any) => {
                            if (item?.image_url) setSelectedBackgroundUrl(String(item.image_url));
                            setSelectedBackgroundItem(item || null);
                            setShowBackgroundPicker(false);
                        }}
                        onClose={() => setShowBackgroundPicker(false)}
                    />
                )}
                {/* Expression 选择弹窗（select_Expression） */}
                {showExpressionPicker && (
                    <SelectExpression
                        belongs={belongsCategory || selectedCharacter?.category}
                        onSelect={(item: any) => {
                            if (item?.image_url) setSelectedExpressionUrl(String(item.image_url));
                            setSelectedExpressionItem(item || null);
                            setShowExpressionPicker(false);
                        }}
                        onClose={() => setShowExpressionPicker(false)}
                    />
                )}

                {/* Presets 模式选择条 暂时不开启 */}
                {/* <div className='mt-2 cursor-pointer'>
                    <div className='h-10 rounded-md dark:bg-[#27272A] bg-[#373737] border border-[#2a2a2a] px-3 flex items-center justify-between text-xs'>
                        <div className='text-[#cbd0d5] text-[0.9rem]'>Mode:</div>
                        <div className='flex-1 px-2 text-[#FAFAFA] text-[0.9rem] font-semibold'>Presets</div>
                        <div className='text-[#cbd0d5]'>›</div>
                    </div>
                </div> */}

                {/* 高级设置开关与内容占位 暂时不开启 */}
                {/* <div className='mt-3'>
                    <div className='flex items-center text-sm text-[#cbd0d5]'>
                        <button onClick={() => setShowAdvanced(v => !v)} className='flex items-center'>
                            <span>Advanced Settings</span>
                            <span className='ml-1'>▾</span>
                        </button>
                    </div>
                    {showAdvanced && (
                        <div className={`mt-2 ${cardClass}`}>
                            <div className={`p-4 text-xs text-[#9ea3a8]`}>
                                这里是高级设置内容占位（分辨率、细节等级、去噪等）。
                            </div>
                        </div>
                    )}
                </div> */}

                {/* 作品库标题 */}
                <div className='mt-8 text-center font-[800] text-[1.3rem]'>
                    <span className='dark:text-white text-[black]'>{t('CreatImg.gallery_title').split(' ')[0]}</span>
                    <span className='ml-2' style={{ color: '#ff87bb' }}>{t('CreatImg.gallery_title').split(' ')[1]}</span>
                    <span className='ml-2 dark:text-white text-[black]'>{t('CreatImg.gallery_title').split(' ').slice(2).join(' ')}</span>

                    {/* 作品列表区：封装到 WorkList 子组件，内部包含生成中/结果/我的作品与懒加载、点赞等交互 */}
                    <div className='mt-4'>
                        <WorkList
                            ref={workListRef}
                            cardClass={cardClass}
                            onOpenImage={(url) => setPreviewUrl(url)}
                            onOpenWork={(w) => setPreviewWork(w)}
                            messageApi={messageApi}
                        />
                    </div>
                </div>

                {/* 提交按钮 */}
                <div className='sticky md:bottom-0 bottom-24 left-0 right-0 mt-6 mb-10 z-10'>
                    <div className='mx-auto md:w-[70%] lg:w-[54%] xl:w-[60%] 2xl:w-[56%] w-[92%] lg:max-w-5xl xl:max-w-6xl 2xl:max-w-[1280px] flex justify-center'>
                        <button
                            onClick={async () => {
                                // 仅在已选择角色时响应
                                if (!selectedCharacter) return;

                                // 统一使用 getStoredBearerToken() 判断登录并获取 Authorization header
                                const authHeader = getStoredBearerToken();
                                if (!authHeader) {
                                    try {
                                        setLoginReturnState({
                                            type: 'createImage',
                                            url: window.location.href,
                                            selectedCharacter,
                                            selectedPoseItem,
                                            selectedOutfitItem,
                                            selectedBackgroundItem,
                                            selectedExpressionItem,
                                            selectedImageUrl,
                                            selectedPoseUrl,
                                            selectedOutfitUrl,
                                            selectedBackgroundUrl,
                                            selectedExpressionUrl,
                                        });
                                    } catch { }
                                    try { openLoginModal('login'); } catch { }
                                    return;
                                }
                                try {
                                    try {
                                        workListRef.current?.showOptimisticLoading?.();
                                        // 下一帧再滚动，确保 DOM 已更新
                                        requestAnimationFrame(() => {
                                            workListRef.current?.scrollToLoading?.();
                                        });
                                    } catch { }

                                    // 收集所有可能的选中项（character, pose, outfit, background, expression）
                                    const itemsForKeys: Array<any> = [
                                        selectedCharacter,
                                        selectedPoseItem,
                                        selectedOutfitItem,
                                        selectedBackgroundItem,
                                        selectedExpressionItem,
                                    ].filter(Boolean);
                                    // user_keyWords: 拼接所有 item.key_words（如果存在），以逗号分隔
                                    const user_keyWords = itemsForKeys
                                        .map((it) => it?.key_words)
                                        .filter((k) => typeof k === 'string' && k.trim().length > 0)
                                        .join(',') || '';
                                    const persion_keyWords = selectedCharacter.role_prompt ?? '';
                                    const select_persion_id = selectedCharacter.id ?? null;
                                    const lang = toApiLanguageCode(locale as any);
                                    const taskParams = {
                                        template_id: Number(select_persion_id),
                                        notify_channel: 'room_test',
                                        role_prompt: String(persion_keyWords || ''),
                                        user_prompt: String(user_keyWords || ''),
                                        self_prompt: String(selfPrompt || ''), // 添加自定义提示词字段
                                        is_public: true,
                                        language: lang,
                                        // 新增 category 字段并传递给后端（若存在）
                                        category: selectedCharacter?.category ?? undefined,
                                    };
                                    const taskId = await generationManager.createTask(taskParams);
                                } catch (e) {
                                    console.error('创建任务时发生错误:', e);
                                    messageApi.error(t('messageApi.create_task_failed'));
                                }
                            }}
                            disabled={!selectedCharacter || !selectedCharacter?.role_prompt?.trim()}
                            style={{
                                background: 'linear-gradient(to right, rgb(236, 72, 153), rgb(244, 114, 182), rgb(236, 72, 153))',
                                opacity: (selectedCharacter && selectedCharacter?.role_prompt?.trim()) ? 1 : 0.4
                            }}
                            className={`h-14 px-10 rounded-md text-sm font-medium text-[white] transition-opacity animate-bounce ${(selectedCharacter && selectedCharacter?.role_prompt?.trim()) ? 'hover:opacity-90' : 'cursor-not-allowed'}`}
                        >
                            {(() => {
                                if (!selectedCharacter) return t('CreatImg.select_character_first');
                                if (!selectedCharacter?.role_prompt?.trim()) return t('CreatImg.select_valid_character');
                                return t('CreatImg.confirm_selection');
                            })()}
                        </button>
                    </div>
                </div>
            </div>
            {/* 预览弹层：生成结果图片（新组件） */}
            <ImagePreviewModal url={previewUrl} onClose={() => setPreviewUrl(null)} />
            {/* 预览弹层：我的作品（新组件，回传可见性与删除事件） */}
            <WorkEditPop
                work={previewWork}
                onClose={() => setPreviewWork(null)}
                onVisibilityChange={(workId: number, isPublic: boolean) => {
                    setPreviewWork((pw: any | null) => pw ? { ...pw, is_public: isPublic } : pw);
                    workListRef.current?.applyWorkVisibility(workId, isPublic);
                }}
                onDeleted={(workId: number) => {
                    workListRef.current?.removeWork(workId);
                    setPreviewWork(null);
                    messageApi.success(t('CreatImg.delete_success'));
                }}
            />
            {showVideoComingSoon && (
                <div className='fixed  inset-0 z-[1500] flex items-center justify-center px-6'>
                    <div className=' absolute inset-0 bg-black/60 backdrop-blur-sm' onClick={() => { setShowVideoComingSoon(false); setTab('image'); }} />
                    <div className=' relative z-10 w-full  rounded-2xl border border-[#ff87bb66] bg-white/95 dark:bg-[#121214] shadow-xl p-8 text-center'>
                        <div className='mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-full bg-gradient-to-br from-[#ec4899] to-[#f472b6] text-white text-2xl'>🎬</div>
                        <div className='text-lg font-semibold text-[#2b2b2b] dark:text-[#fafafa]'>{t('CreatImg.video_coming_title')}</div>
                        <p className='mt-2 text-sm text-[#6b7280] dark:text-[#9ea3a8]'>{t('CreatImg.video_coming_desc')}</p>
                        <button
                            onClick={() => { setShowVideoComingSoon(false); setTab('image'); }}
                            style={{ background: 'linear-gradient(to right, rgb(236, 72, 153), rgb(244, 114, 182), rgb(236, 72, 153))' }}
                            className='mt-6 h-11 w-full rounded-lg text-sm font-medium text-white hover:opacity-90 transition-opacity'
                        >
                            {t('CreatImg.video_coming_button')}
                        </button>
                    </div>
                </div>
            )}
        </div>
    );
};

export default CreateImagePage;
